#include "mainwindowimpl.h"

#define YES 1
#define NO 0
#define EM_LS GSL_CONST_MKSA_SPEED_OF_LIGHT //2.99792458e8		//скорость света

void MainWindowImpl::copyRecord()
{
        int countR=1, countC=2;
	QString Id,records;
	QSqlQuery query;
	query.exec("SELECT "+Base.value(countC)+" FROM wave WHERE id ="+records.setNum(countR));
	query.next();
	records = query.value(0).toString();
	QApplication::clipboard()->setText(records);	//in rignt part returns a pointer to app's clipboard
}

void MainWindowImpl::copyDatabase()
{
	int countR, countC;
	QString Id,records;
	QSqlQuery query;
	countR = waveSqlModel->rowCount();	//load number of rows
	countC = waveSqlModel->columnCount();	//load number of columns
        for (int j=0 ; j < countC ; j++) records += Base.value(j)+"\t";
	records += "\n";
	for (int i=0 ; i<countR ; i++)
	{
        query.exec("SELECT * FROM wave WHERE id ="+Id.setNum(i+1));	//return record number %i
		query.next();	//set position
		for (int j=0 ; j < countC ; j++) 
		{
                        records += query.value(j).toString();  // QVariant value of (i,j) convert to String and writing
			records += "\t";
		}
		records += "\n";
	}
	QApplication::clipboard()->setText(records);	//in rignt part returns a pointer to app's clipboard 
}

void MainWindowImpl::clearDatabase()	//dropping all rows
{
	QSqlQuery query;
	query.exec("DELETE from WAVE");
	waveSqlModel->select();
}

bool MainWindowImpl::save()
{
    QSqlQuery query;
    QString str;
    QString fileName = QFileDialog::getSaveFileName(this,tr("Save components to file..."),"AFR"+str+".csv",tr("Data files (*.csv)"));
    if (fileName.isEmpty()) return false;
    QFile writefile(fileName);
    QTextStream stream(&writefile);
    double coordR,coordFi;
    if(writefile.open(QIODevice::ReadWrite))
    {
        // Parameters
        stream << "Frequency:," << str.setNum(ft.f0) << endl;
        stream << "Radius a:," << str.setNum(ft.a) << endl;
        stream << "Radius b:," << str.setNum(ft.b) << endl;
        stream << "k:," << str.setNum(ft.k) << endl;
        stream << "alfa1:," << str.setNum(ft.alfa1) << endl;
        stream << "Im{alfa2}:," << str.setNum(__imag__(ft.alfa2)) << endl;
        stream << "beta:," << str.setNum(ft.beta) << endl;
        stream << "Area of radiator:," << str.setNum(area) << endl;
        stream << "Method of calculation:," << str.setNum(method) << endl;
        stream << "Fixed parameter:," << str.setNum(param+1) << endl;
        query.exec("SELECT * FROM wave WHERE id =1"); query.next();
        for (int i=0; i<3; i++)
        {
            stream << "Parameter " << str.setNum(i+1) << ":,";
            if (param!=i) stream << query.value(9+i).toString() << endl;
            else stream << "var" << endl;
        }
        //Data
        if (!isSec) stream << tr("\ncoord,Real,Imag,Amp,Arg\n");
        else  stream << tr("\nX,Y,Real,Imag,Amp,Arg\n");
        for (int i=0; i<waveSqlModel->rowCount(); i++)
        {
            query.exec("SELECT * FROM wave WHERE id ="+str.setNum(i+1));
            query.first();	//set position
            if (!isSec) stream << query.value(9+param).toString() << ",";
            else
            {
                coordR=query.value(9).toDouble();
                coordFi=query.value(10).toDouble()/180*M_PI;
                stream << str.setNum(coordR*cos(coordFi)) << ",";
                stream << str.setNum(coordR*sin(coordFi)) << ",";
            }
            stream << query.value(1).toString() << ",";   // vectorE
            stream << query.value(2).toString() << ",";
            stream << query.value(32).toString() << ",";    //Ampl
            stream << query.value(33).toString() << endl;    //Arg
        }
    }
    else QMessageBox::information(0, qApp->tr("Under construction"), qApp->tr("Not developed yet"), QMessageBox::Close);
    writefile.close();
    return true;
}

void MainWindowImpl::about()
{
    QMessageBox::information(0, qApp->tr("NeFeR - Near-field Radiation"),
                 qApp->tr("Calculating of electric field near the open end of circle shielded waveguides.\n\n"
                          "This program is free software: you can redistribute it and/or modify it "
                          "under the terms of the GNU General Public License v.3.\n"
                          "This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; "
                          "without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
                          "You should have received a copy of the GNU General Public License along with this program. "
                          "If not, see http://www.gnu.org/licenses/ \n\n"
                          "Copyright: Dmitry Kravtsov (e-mail: dnkrav@gmail.com)\n"
                          "See more http://code.google.com/p/nefer/"), QMessageBox::Close);
}

void MainWindowImpl::initCalc()
{
    //ft.N=100;   //number of steps for cubaturs
    QDoubleSpinBox* val[3][4]={{boxCirc, boxTwoA, boxResA, boxStripA},
                               {boxKappaC, boxKappaT, boxKappaR, boxKappaS},
                               {boxCE, boxTE1, boxRE, boxSE1}};
    ft.a=val[0][curType]->value()/1000;
    ft.k=val[1][curType]->value()/ft.a;
    ft.e1=val[2][curType]->value();
    if(curType==1) { ft.b=boxTwoB->value()/1000;   ft.e2=boxTE2->value(); }
    //if(curType==3) { ft.b=boxStripB->value()/1000; ft.e2=boxSE2->value(); }
    if(ifRefract->isChecked()) //if refraction installed
    {
        switch (area)
        {
        case 6 : //E01
            ft.Rln[0]=0.7;
            break;
        case 7 : //H01
            ft.Rln[0]=0.36;
            break;
        case 8 : //H11
            ft.Rln[0]=0.28;
            break;
        }
    }
    else ft.Rln[0]=0; //without refraction
    q1=&ft.R;
    if(method==0 || method==1)
    {
        q2=&ft.teta;
        q3=&ft.fi;
        dist=&q3;//dist=&q1;
    }
    if(method==2 || method==3 || method==4 || method==5)
    {
        q2=&ft.fi;
        q3=&ft.Z;
        dist=&q3;
    }
    *q1=boxQ1->value();
    *q2=boxQ2->value();
    *q3=boxQ3->value();
    ft.Z/=1000;    ft.R/=1000;
    //ft.fi*=M_PI/180;
    //ft.teta*=M_PI/180;
    double length=0.0032;
    if(area==0 || area==4) //Far away
    {
        length=ft.a;
        ft.k=2*M_PI/ft.a;
        ft.w=ft.k*EM_LS; ft.f0=ft.w/2/M_PI;
        ft.e1=1; ft.e2=1; ft.m1=1; ft.m2=1;
        //ft.fi*=M_PI/180;
    }
    if(area==1 || area==2 || area==3) //Structure
    {
        ft.k=2*M_PI/length;
        ft.w=ft.k*EM_LS;
        ft.f0=ft.w/2/M_PI;
        //ft.Dist=**dist*2*M_PI/ft.k;
        ft.Dist=**dist;
        ft.m1=1; ft.m2=1;
        ft.alfa();
        ft.beta=sqrt(pow(ft.k,2)*ft.e1*ft.m1-pow(ft.alfa(),2));
        ft.alfa2=1I*sqrt(pow(ft.beta,2)-pow(ft.k,2)*ft.e2*ft.m2);
        ft.I1b=gsl_sf_bessel_I1(__imag__(ft.alfa2)*ft.b);
        ft.I0b=gsl_sf_bessel_I0(__imag__(ft.alfa2)*ft.b);
        ft.K1b=gsl_sf_bessel_K1(__imag__(ft.alfa2)*ft.b);
        ft.K0b=gsl_sf_bessel_K0(__imag__(ft.alfa2)*ft.b);
        ft.G1=ft.G(1);
        ft.G2=ft.G(2);
    }
    if(area==9) // Layer, E01
    {
        ft.difQ[0]=boxPnum->value();
        ft.k=2*M_PI/(0.0032);
        ft.waveType=1;
        ft.alfa1=gsl_sf_bessel_zero_J0(1)/ft.a;
        ft.beta=sqrt(pow(ft.k,2)-pow(ft.alfa1,2));
        ft.w=ft.k*EM_LS;  ft.f0=ft.w/2/M_PI;
        ft.mI=0; ft.nI=1;
        //param=0;
    }
    if(area==6)
    {
        //ft.k=2.552/ft.a;
        ft.alfa1=gsl_sf_bessel_zero_J0(1)/ft.a;
        ft.beta=sqrt(pow(ft.k,2)-pow(ft.alfa1,2));
        ft.w=ft.k*EM_LS;  ft.f0=ft.w/2/M_PI;
        ft.mI=0; ft.nI=1;
        ft.waveType=1;
    }
    if(area==7)
    {
        //ft.alfa1=3.8317059702/ft.a;
        //ft.beta=sqrt(pow(ft.k,2)-pow(ft.alfa1,2));
        ft.w=ft.k*EM_LS;  ft.f0=ft.w/2/M_PI;
        ft.mI=0; ft.nI=1;
        ft.waveType=2;
    }
    if(area==8)
    {
        ft.mI=1; ft.nI=1;
        ft.waveType=2;
        ft.alfa1=ft.zerosJs(ft.mI,ft.nI)/ft.a;
        ft.beta=sqrt(pow(ft.k,2)-pow(ft.alfa1,2));
        ft.w=ft.k*EM_LS;  ft.f0=ft.w/2/M_PI;
    }
    //if(method==3) ft.k=4.023/ft.a;
    if(method==4)
    {
        ft.difQ[1]=spinDm->value(); // number in first
        ft.difQ[2]=spinDn->value(); // number in coax
        ft.difQ[0]=ft.difQ[1]+ft.difQ[2]+1;	//the TEM-wave give "+1"
        ft.difQ[3]=spinDR->value();
    }
    //        ft.teta=boxQ2->value()*M_PI/180;
    //        ft.fi=boxQ3->value()*M_PI/180;
}

